import { ListService, TrackByService } from '@abp/ng.core';
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router';
import { concat } from 'rxjs';
import { GetIdentityUsersInput, IdentityUserDto, IdentityUserService } from '../proxy/identity';
import { RefPermissionService } from '../ref-permission/ref-permission.service';
import { UserDetailComponentService } from '../user-detail/user-detail.component.service';

@Component({
  selector: 'lib-user-list',
  templateUrl: './user-list.component.html',
  styleUrls: ['./user-list.component.less'],
  providers: [ListService],
})
export class UserListComponent implements OnInit {
  models: IdentityUserDto[] = [];
  selectedModels: IdentityUserDto[] = [];
  totalCount: number = 0;

  public get currentPage() {
    return this.listService.page + 1;
  }

  public set currentPage(page: number) {
    this.listService.page = Math.max(page - 1, 0);
  }

  public get maxResultCount() {
    return this.listService.maxResultCount;
  }

  public set maxResultCount(value: number) {
    this.listService.maxResultCount = value;
  }

  get pageCount(): number {
    if (this.totalCount <= 0 || this.listService.maxResultCount <= 0) return 0;
    const pageCount = Math.floor(this.totalCount / this.listService.maxResultCount);
    return this.totalCount % this.listService.maxResultCount == 0 ? pageCount : pageCount + 1;
  }

  get isAllSelected(): boolean {
    return (
      this.models.every(model => this.selectedModels.some(item => item.id === model.id)) &&
      !!this.models?.length
    );
  }
  get indeterminate(): boolean {
    return (
      this.models.some(model => this.selectedModels.some(item => item.id == model.id)) &&
      !this.models.every(model => this.selectedModels.some(item => item.id == model.id))
    );
  }
  get selectedCount(): number {
    return !!this.selectedModels.length ? this.selectedModels.length : 0;
  }

  isDeleteButtonDisabledFn = () => this.selectedCount <= 0;

  constructor(
    public router: Router,
    public route: ActivatedRoute,
    public readonly track: TrackByService,
    public readonly listService: ListService<GetIdentityUsersInput>,
    public entityService: IdentityUserService,
    public userDetailComponentService: UserDetailComponentService,
    public refPermissionService: RefPermissionService
  ) {}

  ngOnInit(): void {
    this.listService.maxResultCount = 10;
    this.listService
      .hookToQuery(query => this.entityService.getList(query))
      .subscribe(listResult => this.renderModels(listResult));
  }

  renderModels(listResult) {
    this.models = listResult.items;
    this.totalCount = listResult.totalCount;
  }

  isModelSelected(model: IdentityUserDto): boolean {
    if (!this.selectedModels?.length) return false;
    if (this.selectedModels.length <= 0) return false;
    return !!this.selectedModels.find(x => x.id == model.id);
  }

  targetModelSelect(model: IdentityUserDto): void {
    if (!this.selectedModels.some(item => item.id === model.id)) {
      this.selectedModels = [...this.selectedModels, model];
    } else {
      this.selectedModels = [...this.selectedModels.filter(item => item.id !== model.id)];
    }
  }

  targetAllSelect() {
    const allselected = this.models.every(model =>
      this.selectedModels.some(item => item.id === model.id)
    );

    if (allselected) {
      this.selectedModels = [
        ...this.selectedModels.filter(item => !this.models.some(model => model.id === item.id)),
      ];
    } else {
      this.selectedModels = [
        ...this.selectedModels,
        ...this.models.filter(model => !this.selectedModels.some(item => model.id === item.id)),
      ];
    }
  }

  clearSelect() {
    this.selectedModels = [];
  }

  new() {
    this.router.navigate(['identity/user-detail']).then(success => {
      if (success) {
        this.userDetailComponentService.new();
      }
    });
  }

  delete() {
    if (this.selectedCount > 0) {
      const ids = this.selectedModels.map(x => x.id);
      concat(
        ...ids.map(id =>
          this.entityService
            .delete(id)
            .toPromise()
            .then(() => (this.selectedModels = this.selectedModels.filter(x => x.id !== id)))
        )
      ).subscribe(() => {
        this.listService.get();
      });
    }
  }

  refresh() {
    this.listService.get();
  }

  view(model, event?: Event) {
    event?.stopPropagation();
    this.router.navigate(['identity/user-detail']).then(success => {
      if (success) {
        this.userDetailComponentService.view(model);
      }
    });
  }

  editPermission(model: IdentityUserDto, event?: Event) {
    event?.stopPropagation();
    this.refPermissionService.show({ providerName: 'U', keyModel: model }).subscribe();
  }

  search(filter: string) {
    this.listService.filter = filter;
  }
}
